/*
 * VHClubHistoryGrid.java
 * Created on 8 août 2009
 *
 * VirtualHockey Internet Platform
 * http://code.google.com/p/virtualhockey/
 *
 * Copyright (c) 2005-2009, Jens and Jan Janke (VirtualHockey Project)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see http://www.gnu.org/licenses/.
 */

package com.hockeo.vhweb.client.ui.widget;

import java.util.ArrayList;
import java.util.List;

import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.Style.SortDir;
import com.extjs.gxt.ui.client.store.GroupingStore;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnData;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.grid.GridCellRenderer;
import com.extjs.gxt.ui.client.widget.grid.GridGroupRenderer;
import com.extjs.gxt.ui.client.widget.grid.GroupColumnData;
import com.extjs.gxt.ui.client.widget.grid.GroupingView;
import com.extjs.gxt.ui.client.widget.grid.RowNumberer;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.google.gwt.i18n.client.NumberFormat;
import com.hockeo.vhweb.client.VHMain;
import com.hockeo.vhweb.client.mvc.VHController;
import com.hockeo.vhweb.client.res.VHResConstants;
import com.hockeo.vhweb.client.rpc.VHRpcResultReceiver;
import com.hockeo.vhweb.client.ui.menu.VHClubInfoContextMenu;
import com.hockeo.vhweb.client.ui.menu.VHGridContextMenu;
import com.hockeo.vhweb.client.utils.VHJsData;
import com.hockeo.vhweb.client.utils.enums.VHJsClubContestHistoryType;

/**
 * Displays club/contest season history records.
 *
 * @version $Id$
 * @author jjanke
 */
public class VHClubHistoryGrid extends LayoutContainer implements VHRpcResultReceiver<List<VHJsData>>
{
  private static final int COL_IDX_CONTEST_ID_TRANSLATED       = 2;
  private static final int COL_IDX_CONTEST_CATEGORY            = 3;
  private static final int COL_IDX_STANDINGS_RANK_TYPE         = 6;
  private static final int COL_IDX_REACHED_ROUND_TRANSLATED    = 7;
  private static final int COL_IDX_STANDINGS_NUM_GOALS_FOR     = 14;
  private static final int COL_IDX_STANDINGS_NUM_GOALS_AGAINST = 15;
  private static final int COL_IDX_STANDINGS_GOALS_DIFF        = 16;
  private static final int COL_IDX_FIRST_ROUND                 = 19;
  private static final int COL_IDX_LAST_ROUND                  = 20;
  private static final int COL_IDX_NUM_WON_KO_SERIES           = 21;
  private static final int COL_IDX_NUM_LOST_KO_SERIES          = 22;
  private static final int COL_IDX_NUM_QUALIFICATION_ROUNDS    = 23;

  public enum HistoryDisplayType
  {
    /** Display data for a single club (possibly covering multiple seasons). */
    SINGLE_CLUB,

    /** Display data for more than one club covering a single season (and contest). */
    MULTI_CLUB;
  }

  private final VHGridContextMenu d_ctxmenu;
  private Grid<VHJsData>          d_grid;
  private GroupingStore<VHJsData> d_store;
  private HistoryDisplayType      d_displayType;

  public VHClubHistoryGrid( VHController controller, HistoryDisplayType displayType )
  {
    d_store = new GroupingStore<VHJsData>();
    d_displayType = displayType;

    buildGrid();
    setLayout( new FitLayout() );
    add( d_grid );

    // We only add a context menu, if multiple clubs are displayed
    //
    if ( d_displayType == HistoryDisplayType.MULTI_CLUB )
      d_ctxmenu = new VHClubInfoContextMenu( controller, d_grid, "club_" );
    else
      d_ctxmenu = null;
  }

  public void setRpcData( List<VHJsData> listRecords, String strPurpose )
  {
    d_store.removeAll();
    d_store.add( listRecords );

    if ( d_displayType == HistoryDisplayType.MULTI_CLUB )
    {
      d_store.groupBy( "reachedRound_order" );
      d_store.sort( "rank", SortDir.ASC );
    }
    else
    {
      // Using the purpose we can discover what kind of data has been transmitted. We use
      // it to enable/disable certain columns.
      //
      if ( strPurpose != null )
      {
        VHJsClubContestHistoryType d_type = VHJsClubContestHistoryType.valueOf( strPurpose );
        ColumnModel cm = d_grid.getColumnModel();

        switch ( d_type )
        {
          case NATIONAL_LEAGUE:
          {
            cm.setHidden( COL_IDX_CONTEST_ID_TRANSLATED, false );
            cm.setHidden( COL_IDX_CONTEST_CATEGORY, false );
            cm.setHidden( COL_IDX_STANDINGS_RANK_TYPE, false );
            cm.setHidden( COL_IDX_REACHED_ROUND_TRANSLATED, true );
            cm.setHidden( COL_IDX_STANDINGS_NUM_GOALS_FOR, false );
            cm.setHidden( COL_IDX_STANDINGS_NUM_GOALS_AGAINST, false );
            cm.setHidden( COL_IDX_STANDINGS_GOALS_DIFF, false );
            cm.setHidden( COL_IDX_FIRST_ROUND, true );
            cm.setHidden( COL_IDX_LAST_ROUND, true );
            cm.setHidden( COL_IDX_NUM_WON_KO_SERIES, true );
            cm.setHidden( COL_IDX_NUM_LOST_KO_SERIES, true );
            cm.setHidden( COL_IDX_NUM_QUALIFICATION_ROUNDS, true );
            break;
          }

          case NATIONAL_CUP:
          {
            cm.setHidden( COL_IDX_CONTEST_ID_TRANSLATED, true );
            cm.setHidden( COL_IDX_CONTEST_CATEGORY, true );
            cm.setHidden( COL_IDX_STANDINGS_RANK_TYPE, true );
            cm.setHidden( COL_IDX_REACHED_ROUND_TRANSLATED, false );
            cm.setHidden( COL_IDX_STANDINGS_NUM_GOALS_FOR, true );
            cm.setHidden( COL_IDX_STANDINGS_NUM_GOALS_AGAINST, true );
            cm.setHidden( COL_IDX_STANDINGS_GOALS_DIFF, true );
            cm.setHidden( COL_IDX_FIRST_ROUND, false );
            cm.setHidden( COL_IDX_LAST_ROUND, false );
            cm.setHidden( COL_IDX_NUM_WON_KO_SERIES, false );
            cm.setHidden( COL_IDX_NUM_LOST_KO_SERIES, false );
            cm.setHidden( COL_IDX_NUM_QUALIFICATION_ROUNDS, true );
            break;
          }

          case INTERNATIONAL_CUP:
          {
            cm.setHidden( COL_IDX_CONTEST_ID_TRANSLATED, false );
            cm.setHidden( COL_IDX_CONTEST_CATEGORY, true );
            cm.setHidden( COL_IDX_STANDINGS_RANK_TYPE, true );
            cm.setHidden( COL_IDX_REACHED_ROUND_TRANSLATED, false );
            cm.setHidden( COL_IDX_STANDINGS_NUM_GOALS_FOR, true );
            cm.setHidden( COL_IDX_STANDINGS_NUM_GOALS_AGAINST, true );
            cm.setHidden( COL_IDX_STANDINGS_GOALS_DIFF, true );
            cm.setHidden( COL_IDX_FIRST_ROUND, true );
            cm.setHidden( COL_IDX_LAST_ROUND, true );
            cm.setHidden( COL_IDX_NUM_WON_KO_SERIES, false );
            cm.setHidden( COL_IDX_NUM_LOST_KO_SERIES, false );
            cm.setHidden( COL_IDX_NUM_QUALIFICATION_ROUNDS, false );
            break;
          }

          default:
          {
            cm.setHidden( COL_IDX_CONTEST_ID_TRANSLATED, false );
            cm.setHidden( COL_IDX_STANDINGS_RANK_TYPE, true );
            cm.setHidden( COL_IDX_REACHED_ROUND_TRANSLATED, false );
            cm.setHidden( COL_IDX_STANDINGS_NUM_GOALS_FOR, true );
            cm.setHidden( COL_IDX_STANDINGS_NUM_GOALS_AGAINST, true );
            cm.setHidden( COL_IDX_STANDINGS_GOALS_DIFF, true );
            cm.setHidden( COL_IDX_FIRST_ROUND, false );
            cm.setHidden( COL_IDX_LAST_ROUND, false );
            cm.setHidden( COL_IDX_NUM_WON_KO_SERIES, false );
            cm.setHidden( COL_IDX_NUM_LOST_KO_SERIES, false );
            cm.setHidden( COL_IDX_NUM_QUALIFICATION_ROUNDS, false );
          }
        }
      }

      d_store.clearGrouping();
      d_store.sort( "season_name", SortDir.DESC );
    }
  }

  private void buildGrid()
  {
    // Cell rendering
    //
    final NumberFormat numberFormat = NumberFormat.getFormat( "0.0" );
    GridCellRenderer<VHJsData> renderer = new GridCellRenderer<VHJsData>() {
      public String render( VHJsData chr, String strProperty, ColumnData config, int rowIndex, int colIndex,
          ListStore<VHJsData> store, Grid<VHJsData> grid )
      {
        if ( strProperty.equals( "medal" ) )
        {
          String strMedal = chr.getString( strProperty );

          if ( !strMedal.equals( "NONE" ) )
          {
            String strTooltip = VHMain.getLookupConstants().getString( "medal" + strMedal );

            return "<img src='images/picto/medal_" + strMedal.toLowerCase() + ".png' title='" + strTooltip + "'/>";
          }

          return "";
        }
        else if ( strProperty.equals( "club_country" ) )
          return "<img src='images/flags/16x16/" + chr.getString( strProperty ) + ".png'/>";
        else if ( strProperty.equals( "pointsPercentage" ) )
          return numberFormat.format( chr.getDouble( strProperty ) * 100.0 );
        else if ( strProperty.equals( "pointsECR" ) )
          return numberFormat.format( chr.getDouble( strProperty ) );
        else if ( strProperty.equals( "rank" ) )
        {
          int nVal = chr.getInt( strProperty );
          if ( nVal == 1 )
            return "<span style='font-weight: bold; font-style: italic; color: red;'>" + nVal + "</span>";
          else
            return "<span style='font-weight: bold; font-style: italic;'>" + nVal + "</span>";
        }
        else if ( strProperty.equals( "standings_rankType" ) && chr.getString( strProperty ) != null )
        {
          String strType = chr.getString( strProperty );
          String strTooltip = chr.getString( strProperty + "_translated" );
          String strImg;

          if ( strType.equals( "QUALIFIED_EU1" ) )
            strImg = "rank_eu1.png";
          else if ( strType.equals( "QUALIFIED_EU2" ) )
            strImg = "rank_eu2.png";
          else if ( strType.equals( "MIDFIELD" ) )
            strImg = "rank_midfield.gif";
          else if ( strType.equals( "RELEGATED" ) )
            strImg = "rank_relegated.gif";
          else
            strImg = "rank_promoted.gif";

          return "<img src='images/picto/" + strImg + "' title='" + strTooltip + "'/>";
        }

        return String.valueOf( chr.get( strProperty ) );
      }
    };

    // Column definitions
    //
    VHResConstants constants = VHMain.getConstants();
    ArrayList<ColumnConfig> listCols = new ArrayList<ColumnConfig>();
    ColumnConfig col;

    RowNumberer rowNumberer = new RowNumberer();
    listCols.add( rowNumberer );

    if ( d_displayType == HistoryDisplayType.MULTI_CLUB )
    {
      col = new ColumnConfig();
      col.setId( "reachedRound_order" );
      col.setWidth( 26 );
      col.setAlignment( HorizontalAlignment.RIGHT );
      col.setResizable( false );
      col.setHidden( true );
      col.setMenuDisabled( true );
      listCols.add( col );
    }
    else
    {
      col = new ColumnConfig();
      col.setId( "season_name" );
      col.setHeader( constants.season() );
      col.setWidth( 70 );
      col.setAlignment( HorizontalAlignment.LEFT );
      col.setResizable( true );
      col.setMenuDisabled( true );
      listCols.add( col );

      col = new ColumnConfig();
      col.setId( "contest_id_translated" );
      col.setHeader( constants.contestName() );
      col.setWidth( 120 );
      col.setAlignment( HorizontalAlignment.LEFT );
      col.setResizable( true );
      col.setHidden( false );
      col.setMenuDisabled( true );
      listCols.add( col );

      col = new ColumnConfig();
      col.setId( "contest_category" );
      col.setHeader( constants.leagueCategoryAbbrev() );
      col.setToolTip( constants.leagueCategory() );
      col.setWidth( 28 );
      col.setAlignment( HorizontalAlignment.RIGHT );
      col.setResizable( true );
      col.setMenuDisabled( true );
      listCols.add( col );
    }

    col = new ColumnConfig();
    col.setId( "rank" );
    col.setHeader( constants.rankAbbrev() );
    col.setToolTip( constants.rank() );
    col.setWidth( 28 );
    col.setAlignment( HorizontalAlignment.RIGHT );
    col.setResizable( false );
    col.setMenuDisabled( true );
    if ( d_displayType == HistoryDisplayType.SINGLE_CLUB )
      col.setRenderer( renderer );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( "medal" );
    col.setHeader( constants.medalAbbrev() );
    col.setToolTip( constants.medal() );
    col.setWidth( 28 );
    col.setAlignment( HorizontalAlignment.CENTER );
    col.setResizable( false );
    col.setMenuDisabled( true );
    col.setRenderer( renderer );
    listCols.add( col );

    if ( d_displayType == HistoryDisplayType.MULTI_CLUB )
    {
      col = new ColumnConfig();
      col.setId( "club_country" );
      col.setHeader( constants.countryAbbrev() );
      col.setToolTip( constants.country() );
      col.setWidth( 26 );
      col.setRenderer( renderer );
      col.setAlignment( HorizontalAlignment.CENTER );
      col.setResizable( false );
      col.setMenuDisabled( true );
      listCols.add( col );

      col = new ColumnConfig();
      col.setId( "club_name" );
      col.setHeader( constants.clubName() );
      col.setWidth( 200 );
      col.setMenuDisabled( true );
      listCols.add( col );
    }
    else
    {
      col = new ColumnConfig();
      col.setId( "standings_rankType" );
      col.setHeader( constants.rankTypeAbbrev() );
      col.setToolTip( constants.rankType() );
      col.setWidth( 26 );
      col.setAlignment( HorizontalAlignment.CENTER );
      col.setResizable( false );
      col.setRenderer( renderer );
      col.setMenuDisabled( true );
      listCols.add( col );

      col = new ColumnConfig();
      col.setId( "reachedRound_translated" );
      col.setHeader( constants.reachedRound() );
      col.setWidth( 120 );
      col.setAlignment( HorizontalAlignment.LEFT );
      col.setResizable( true );
      col.setMenuDisabled( true );
      listCols.add( col );
    }

    col = new ColumnConfig();
    col.setId( "numMatches" );
    col.setHeader( constants.numMatchesAbbrev() );
    col.setToolTip( constants.numMatches() );
    col.setWidth( 30 );
    col.setAlignment( HorizontalAlignment.RIGHT );
    col.setMenuDisabled( true );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( "numPoints" );
    col.setHeader( constants.numPointsAbbrev() );
    col.setToolTip( constants.numPoints() );
    col.setWidth( 30 );
    col.setAlignment( HorizontalAlignment.RIGHT );
    col.setMenuDisabled( true );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( "numWins" );
    col.setHeader( constants.numWinsAbbrev() );
    col.setToolTip( constants.numWins() );
    col.setWidth( 30 );
    col.setAlignment( HorizontalAlignment.RIGHT );
    col.setMenuDisabled( true );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( "numWinsOT" );
    col.setHeader( constants.numWinsOtAbbrev() );
    col.setToolTip( constants.numWinsOt() );
    col.setWidth( 30 );
    col.setAlignment( HorizontalAlignment.RIGHT );
    col.setMenuDisabled( true );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( "numLossesOT" );
    col.setHeader( constants.numLossesOtAbbrev() );
    col.setToolTip( constants.numLossesOt() );
    col.setWidth( 30 );
    col.setAlignment( HorizontalAlignment.RIGHT );
    col.setMenuDisabled( true );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( "numLosses" );
    col.setHeader( constants.numLossesAbbrev() );
    col.setToolTip( constants.numLosses() );
    col.setWidth( 30 );
    col.setAlignment( HorizontalAlignment.RIGHT );
    col.setMenuDisabled( true );
    listCols.add( col );

    if ( d_displayType == HistoryDisplayType.SINGLE_CLUB )
    {
      col = new ColumnConfig();
      col.setId( "standings_numGoalsFor" );
      col.setHeader( constants.numGoalsForAbbrev() );
      col.setToolTip( constants.numGoalsFor() );
      col.setWidth( 30 );
      col.setAlignment( HorizontalAlignment.RIGHT );
      col.setMenuDisabled( true );
      listCols.add( col );

      col = new ColumnConfig();
      col.setId( "standings_numGoalsAgainst" );
      col.setHeader( constants.numGoalsAgainstAbbrev() );
      col.setToolTip( constants.numGoalsAgainst() );
      col.setWidth( 30 );
      col.setAlignment( HorizontalAlignment.RIGHT );
      col.setMenuDisabled( true );
      listCols.add( col );

      col = new ColumnConfig();
      col.setId( "standings_goalsDiff" );
      col.setHeader( constants.goalsDiffAbbrev() );
      col.setToolTip( constants.goalsDiff() );
      col.setWidth( 30 );
      col.setAlignment( HorizontalAlignment.RIGHT );
      col.setMenuDisabled( true );
      col.setNumberFormat( NumberFormat.getFormat( "+#;-#" ) );
      listCols.add( col );
    }

    col = new ColumnConfig();
    col.setId( "pointsPercentage" );
    col.setHeader( constants.pointsPctAbbrev() );
    col.setToolTip( constants.pointsPct() );
    col.setWidth( 40 );
    col.setRenderer( renderer );
    col.setAlignment( HorizontalAlignment.RIGHT );
    col.setMenuDisabled( true );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( "pointsECR" );
    col.setHeader( constants.pointsECRAbbrev() );
    col.setToolTip( constants.pointsECR() );
    col.setWidth( 40 );
    col.setRenderer( renderer );
    col.setAlignment( HorizontalAlignment.RIGHT );
    col.setMenuDisabled( true );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( "firstRound" );
    col.setHeader( constants.firstRoundAbbrev() );
    col.setToolTip( constants.firstRound() );
    col.setWidth( 30 );
    col.setAlignment( HorizontalAlignment.RIGHT );
    col.setMenuDisabled( true );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( "lastRound" );
    col.setHeader( constants.lastRoundAbbrev() );
    col.setToolTip( constants.lastRound() );
    col.setWidth( 30 );
    col.setAlignment( HorizontalAlignment.RIGHT );
    col.setMenuDisabled( true );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( "numWonKOSeries" );
    col.setHeader( constants.numWonKoSeriesAbbrev() );
    col.setToolTip( constants.numWonKoSeries() );
    col.setWidth( 30 );
    col.setAlignment( HorizontalAlignment.RIGHT );
    col.setMenuDisabled( true );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( "numLostKOSeries" );
    col.setHeader( constants.numLostKoSeriesAbbrev() );
    col.setToolTip( constants.numLostKoSeries() );
    col.setWidth( 30 );
    col.setAlignment( HorizontalAlignment.RIGHT );
    col.setMenuDisabled( true );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( "numQualificationRounds" );
    col.setHeader( constants.numQualiRoundsAbbrev() );
    col.setToolTip( constants.numQualiRounds() );
    col.setWidth( 30 );
    col.setAlignment( HorizontalAlignment.RIGHT );
    col.setMenuDisabled( true );
    listCols.add( col );

    final ColumnModel cm = new ColumnModel( listCols );

    // Grouping view with customised titles
    //
    GroupingView view = new GroupingView();

    view.setForceFit( true );
    view.setEnableGroupingMenu( false );
    view.setGroupRenderer( new GridGroupRenderer() {
      public String render( GroupColumnData data )
      {
        VHJsData chrFirst = (VHJsData) data.models.get( 0 );

        return chrFirst.getString( "reachedRound_translated" );
      }
    } );

    // Grid
    //
    d_grid = new Grid<VHJsData>( d_store, cm );
    d_grid.addPlugin( rowNumberer );
    d_grid.setView( view );
    d_grid.setStripeRows( true );
    d_grid.setBorders( true );
    d_grid.setAutoWidth( true );
  }
}
